<?php

	include('facebook.php');

	class Facebook_Communicator{

		/**
		 * Facebook class instance.
		 * @var object
		 */
		private $fb;
		
		/**
		 *	User id of the authorized user.
		 * @var int
		 */
		public $user;

		/**
		 * Users model instance.
		 * @var object
		 */
		private $users;

		/**
		 * Is the user logged in?
		 * @var bool
		 */
		public $userIsLoggedIn;

		/**
		 * Url to login or logout depending on the user login state.
		 * @var string
		 */
		public $authUrl;

		public function __construct(){
			$this->users = new Users();
			$this->fb = new Facebook(array(
				'appId' => '227422103950955',
				'secret' => '9cded90b4f0ca39dde596b29710c2548'
			));

			$this->getUserAuthorization();
		}
		
		/**
		 *
		 * @return object reference to facebook class instance.
		 */
		public function &getFb(){
			return $this->fb;
		}

		/**
		 * This function will authorize the user and create/update with database.
		 */
		private function getUserAuthorization(){
			$this->user = $this->fb->getUser();
			
			// If the user is not logged in.
			if($this->user !== 0){
				$this->userIsLoggedIn = true;
				$this->authUrl = $this->fb->getLogoutUrl(array(
					'next' => URL . 'index/logout'
				));

				// Now we are going to involve our model and check whether the user
				// is registered on Hikle or not.
				if($this->users->exists($this->user)){
					$updates = $this->users->readUserUpdates($this->user);

					// If we have to update both, just 
					if($updates['friends'] && $updates['profile']){
						$this->createUser();
					} else if($updates['friends']){
						$this->updateFriends();
					} else if($updates['profile']){
						$this->updateProfile();
					}

					// Either way we just update the update fields in the user row.
					if($updates['friends'] || $updates['profile']){
						$this->users->update($this->user, array('updateFriends', 'updateProfile'), array(0, 0));
					}

				} else {
					$this->createUser();
				}
			} else {
				$this->userIsLoggedIn = false;
				$this->authUrl = $this->fb->getLoginUrl(array(
					'scope' => 'email,user_relationship_details,user_relationships,user_birthday,offline_access,user_hometown,publish_stream',
					'redirect_uri' => URL . 'index/home'
				));
			}
		}

		/**
		 * Do a facebook query, and insert the user in the database.
		 */
		private function createUser(){

			// Delete the user first.
			$this->users->deleteFull($this->user);

			// Query Facebook to get the user data.
			$fbQuery = $this->fb->api('/fql?q=' . urlencode('{"profile":"SELECT name, first_name, birthday_date, hometown_location, current_location, significant_other_id, email, relationship_status, locale, friend_count, sex, meeting_sex FROM user WHERE uid = me()", "friends":"SELECT uid, name FROM user WHERE uid = me() OR uid IN (SELECT uid2 FROM friend WHERE uid1 = me())"}'));
			$profile = $this->fixProfileData($fbQuery['data'][1]['fql_result_set'][0]);
			$profile['isPublic'] = 1;

			// Insert the user in the database.
			$this->users->create($profile);

			// Insert the user in the database.
			$this->users->createFriends($this->user, $fbQuery['data'][0]['fql_result_set']);
		}

		/**
		 * The profile data from fql gets converted in to "database" ready data.
		 * 
		 * @param array $profile
		 * @return array fixed profile data
		 */
		private function fixProfileData($profile){
			$fixedProfile = array(
				'id' => (string)$this->user,
				'firstName' => utf8_decode(strtolower($profile['first_name'])),
				'name' => utf8_decode(strtolower($profile['name'])),
				'email' => utf8_decode($profile['email']),
				'friendCount' => $profile['friend_count'],
				'sex' => $profile['sex'],
				'locale' => $profile['locale'],
				'relationshipStatus' => strtolower($profile['relationship_status']),
				'interestedInFemale' => false,
				'interestedInMale' => false,
				'sigOtherId' => (string)$profile['significant_other_id'],
				'birthday' => dateToMysqlFormat($profile['birthday_date']),
				'hometown' => utf8_decode(strtolower($profile['hometown_location']['city'])),
				'location' => utf8_decode(strtolower($profile['current_location']['city']))
			);

			if(isset($profile['meeting_sex'][0])){
				$fixedProfile['interestedInFemale'] = true;

				if(isset($profile['meeting_sex'][1])){
					$fixedProfile['interestedInMale'] = true;
				}
			}

			return $fixedProfile;
		}

		/**
		 * Updates the friends of the user.
		 */
		private function updateFriends(){
			$fbQuery = $this->fb->api('/fql?q=' . urlencode('SELECT uid, name FROM user WHERE uid = me() OR uid IN (SELECT uid2 FROM friend WHERE uid1 = me())'));

			// First delete all the friends of the user.
			$this->users->deleteFriends($this->user);

			// Now we insert the friends.
			$this->users->createFriends($this->user, $fbQuery['data']);
		}

		/**
		 * Updates the profile data of the user.
		 */
		private function updateProfile(){
			$fbQuery = $this->fb->api('/fql?q=' . urlencode('SELECT name, first_name, birthday_date, hometown_location, current_location, significant_other_id, email, relationship_status, locale, friend_count, sex, meeting_sex FROM user WHERE uid = me()'));
			$profile = $this->fixProfileData($fbQuery['data'][0]);
			$profile['isPublic'] = $this->users->read($this->user, array('isPublic'));
			
			// First delete all the friends of the user.
			$this->users->deleteProfile($this->user);

			// Now we insert the friends.
			$this->users->create($profile);
		}
	}

// File end.